"""
工作表操作
"""
import lark_oapi as lark
from lark_oapi.api.sheets.v3 import *
from lark_oapi.api.sheets.v3 import Sheet

from common.client import get_client
from common.cache_util import cache

# 获取某个工作表
def get(spreadsheet_token,sheet_title):
    sheets = lst(spreadsheet_token)
    for s in sheets:
        if s.title == sheet_title:
            return s
    return None

# 查询工作表(这里需要从飞书重新获取最新的数据)
def query(spreadsheet_token,sheet_title) -> Sheet:
    sheets = lst(spreadsheet_token)
    for s in sheets:
        if s.title == sheet_title:
            # 构造请求对象
            return __query_sheet(spreadsheet_token,s.sheet_id)

    raise None

# 查询工作表
def lst(spreadsheet_token) -> List[Sheet]:
    key = f"spreadsheets:{spreadsheet_token}"
    sheets = cache.get(key)
    if sheets:
        return sheets
    sheets = __query(spreadsheet_token)
    cache.set(key, sheets)
    return sheets

# 增加工作表
def add(spreadsheet_token, sheet_title,index=-1):
    client = get_client()
    sheets = lst(spreadsheet_token)
    uri = f"/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update"
    param = {
        "requests": [
            {
                "addSheet": {
                    "properties": {
                        "title": sheet_title,
                        "index": len(sheets) + 1 if index == -1 else index
                    }
                }
            }
        ]
    }

    request: lark.BaseRequest = lark.BaseRequest.builder() \
        .http_method(lark.HttpMethod.POST) \
        .uri(uri) \
        .token_types({lark.AccessTokenType.TENANT}) \
        .body(param) \
        .build()

    response : lark.BaseResponse = client.request(request)
    if not response.success():
        raise RuntimeError(f"新增工作表失败,失败原因:{response.msg}")
    # 更新后删除缓存
    key = f"spreadsheets:{spreadsheet_token}"
    cache.delete(key)

# 删除工作表
def delete(spreadsheet_token, sheet_title):
    st = get(spreadsheet_token, sheet_title)
    client = get_client()
    uri = f"/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update"
    param = {
        "requests": [
            {
                "deleteSheet": {
                    "sheetId": st.sheet_id,
                }
            }
        ]
    }

    request: lark.BaseRequest = lark.BaseRequest.builder() \
        .http_method(lark.HttpMethod.POST) \
        .uri(uri) \
        .token_types({lark.AccessTokenType.TENANT}) \
        .body(param) \
        .build()

    response: lark.BaseResponse = client.request(request)
    if not response.success():
        raise RuntimeError(f"删除工作表失败,失败原因:{response.msg}")
    # 更新后删除缓存
    key = f"spreadsheets:{spreadsheet_token}"
    cache.delete(key)

# 复制工作表
def copy(spreadsheet_token, source_sheet_title, target_sheet_title):
    st = get(spreadsheet_token, source_sheet_title)
    client = get_client()
    uri = f"/open-apis/sheets/v2/spreadsheets/{spreadsheet_token}/sheets_batch_update"
    param = {
        "requests": [
            {
                "copySheet": {
                    "source": {
                        "sheetId": st.sheet_id,
                    },
                    "destination": {
                        "title": target_sheet_title
                    }
                }
            }
        ]
    }

    request: lark.BaseRequest = lark.BaseRequest.builder() \
        .http_method(lark.HttpMethod.POST) \
        .uri(uri) \
        .token_types({lark.AccessTokenType.TENANT}) \
        .body(param) \
        .build()

    response: lark.BaseResponse = client.request(request)
    if not response.success():
        raise RuntimeError(f"复制工作表失败,失败原因:{response.msg}")

    # 更新后删除缓存
    key = f"spreadsheets:{spreadsheet_token}"
    cache.delete(key)

# 从飞书获取工作表格
def __query(spreadsheet_token) -> List[Sheet]:
    client = get_client()
    # 构造请求对象
    request: QuerySpreadsheetSheetRequest = QuerySpreadsheetSheetRequest.builder() \
        .spreadsheet_token(spreadsheet_token) \
        .build()

    # 发起请求
    response: QuerySpreadsheetSheetResponse = client.sheets.v3.spreadsheet_sheet.query(request)

    # 处理失败返回
    if not response.success():
        raise RuntimeError(f"获取工作表失败,失败原因:{response.msg}")

    return response.data.sheets

# 从飞书获取工作表格
def __query_sheet(spreadsheet_token,sheet_id) -> Sheet:
    client = get_client()
    # 构造请求对象
    request: GetSpreadsheetSheetRequest = GetSpreadsheetSheetRequest.builder() \
        .spreadsheet_token(spreadsheet_token) \
        .sheet_id(sheet_id) \
        .build()

    # 发起请求
    response: GetSpreadsheetSheetResponse = client.sheets.v3.spreadsheet_sheet.get(request)

    # 处理失败返回
    if not response.success():
        raise RuntimeError(f"获取工作表失败,失败原因:{response.msg}")

    return response.data.sheet